package com.learnhow.springboot.web.controller;

import com.learnhow.springboot.web.common.RRException;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.learnhow.springboot.web.PasswordHelper;
import com.learnhow.springboot.web.entity.User;
import com.learnhow.springboot.web.service.UserService;

/**
 * 不需要权限访问的资源
 */
@RestController
@RequestMapping
public class HomeController {
    @Autowired
    private UserService userService;
    @Autowired
    private PasswordHelper passwordHelper;

    @GetMapping("login")
    public Object login() {
        return "Here is Login page";
    }

    /**
     * 没有权限的访问会跳转这里，如访问/authc/admin，但当前角色不是admin
     * @return
     */
    @GetMapping("unauthc")
    public Object unauthc() {
        return "Here is Unauthc page";
    }

    /**
     * 登录
     * @param username
     * @param password
     * @return
     */
    @GetMapping("doLogin")
    public Object doLogin(@RequestParam String username, @RequestParam String password) {
        //1、使用用户的登录信息创建令牌
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        //2、执行登录动作，SecurityUtils 需要注入SecurityManager， subject 为当前被shiro管理的项目
        Subject subject = SecurityUtils.getSubject();
        try {
            //shiro 内部封装校验算法，注册时使用的散列加盐算法，登录时使用相同的算法比对加密后的数据，校验不通过以异常的形式抛出。
            subject.login(token);
        } catch (IncorrectCredentialsException ice) {
            return "password error!";
        } catch (UnknownAccountException uae) {
            return "username error!";
        }

        User user = userService.findUserByName(username);
        subject.getSession().setAttribute("user", user);
        return "SUCCESS";
    }

    /**
     * 注册
     * @param username
     * @param password
     * @return
     */
    @GetMapping("register")
    public Object register(@RequestParam String username, @RequestParam String password) {
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        passwordHelper.encryptPassword(user);  //散列算法加密密码，不可解密

        userService.saveUser(user);
        return "SUCCESS";
    }

    @GetMapping("/hello")
    public String hello(){

        return "hello world";
    }

    /**
     * 前台访问 http://localhost:8080/hello2 页面返回 {"msg":"自定义异常抛出","code":500}
     * controller 方法测试，访问/hello 控制台抛出异常
     * @return
     * @throws Exception
     */
    @GetMapping("/hello2")
    public int exception() throws Exception{
        throw new RRException("自定义异常抛出",500);
    }

}
